package com.gzhryc.shared_device.cdcz.core.protocol.v1;

import com.gzhryc.common.StringTools;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.shared_device.cdcz.core.CDCZConstants;
import com.gzhryc.shared_device.cdcz.core.protocol.v1.models.BKVData;
import com.gzhryc.shared_device.cdcz.core.protocol.v1.models.PlugBKVData;
import com.gzhryc.shared_device.iot.core.IOTMessage;

import java.io.Serializable;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class V1_CDCZ_IOTMessage extends IOTMessage implements Serializable {

    private static final long serialVersionUID = 1L;

    static Logger log = Logger.getLogger(V1_CDCZ_IOTMessage.class);

    private String startFlag = "fcfe";
    private String endFlag = "fcee";

    private Map<String, BKVData> bkvDataMap;

    public V1_CDCZ_IOTMessage() {
        super();
        this.bkvDataMap = new HashMap<>();
    }

    public V1_CDCZ_IOTMessage(byte[] bytes) {
        super(bytes);
        this.bkvDataMap = new HashMap<>();
        this.protocolType = CDCZConstants.ProtocolTypeV1;

        byte[] startBytes = new byte[]{bytes[0],bytes[1]};
        String startStr = StringTools.byteArr2HexStr(startBytes).toLowerCase();
        if(startFlag.equals(startStr)){
            byte[] lengthBytes = new byte[]{bytes[2],bytes[3]};
            String lengthStr = StringTools.byteArr2HexStr(lengthBytes);
            int length = Integer.valueOf(lengthStr,16) + 2;
            byte[] endBytes = new byte[]{bytes[length + 1],bytes[length + 2]};
            String endStr = StringTools.byteArr2HexStr(endBytes).toLowerCase();
            if(endFlag.equals(endStr)){
                byte[] frameCheckBytes = new byte[]{bytes[length]};     //帧校验
                byte[] contentBytes = Arrays.copyOfRange(bytes,4,length);
                analysisBKVData(contentBytes,0);
            }else{
                log.error("报文解析失败，结束标示错误");
            }
        }else{
            log.error("报文解析失败，起始标示错误");
        }
    }

    private void analysisBKVData(byte[] contentBytes,int startNum){
        if(contentBytes.length > startNum) {
            int dataLength = Integer.valueOf(StringTools.byteArr2HexStr(new byte[]{contentBytes[startNum]}),16);
            byte[] data = Arrays.copyOfRange(contentBytes, startNum + 1, startNum + 1 + dataLength);
            int keyLength = Integer.valueOf(StringTools.byteArr2HexStr(new byte[]{data[0]}),16);
            byte[] keyBytes = Arrays.copyOfRange(data, 1, 1 + keyLength);
            byte[] valueBytes = Arrays.copyOfRange(data, keyLength + 1, dataLength);

            String key = StringTools.byteArr2HexStr(keyBytes).toUpperCase();
            if(V1_CDCZConstants.KEY_CMD.equals(key)){
                this.cmd = StringTools.byteArr2HexStr(valueBytes);
            }else if(V1_CDCZConstants.KEY_MSG_ID.equals(key)){
                this.messageId = StringTools.byteArr2HexStr(valueBytes);
            }else if(V1_CDCZConstants.KEY_MAC.equals(key)){
                this.deviceSn = StringTools.byteArr2HexStr(valueBytes);
            }else {
                BKVData bkvData = new BKVData();
                bkvData.setData(data);
                bkvData.setDataLength(dataLength);
                bkvData.setKeyLength(keyLength);
                bkvData.setKey(key);
                bkvData.setValue(valueBytes);
                this.bkvDataMap.put(bkvData.getKey(),bkvData);
            }

            startNum = startNum + dataLength + 1;
            analysisBKVData(contentBytes, startNum);
        }
    }

    public byte[] getBKVValue(String key){
        BKVData bkvData = bkvDataMap.get(key);
        if(bkvData != null){
            return bkvData.getValue();
        }
        return null;
    }

    public String getBKVHexValue(String key){
        BKVData bkvData = bkvDataMap.get(key);
        if(bkvData != null){
            return bkvData.getHexValue();
        }
        return null;
    }

    public String getBKVStringValue(String key){
        BKVData bkvData = bkvDataMap.get(key);
        if(bkvData != null){
            return bkvData.getStringValue();
        }
        return null;
    }

    public Integer getBKVIntegerValue(String key){
        BKVData bkvData = bkvDataMap.get(key);
        if(bkvData != null){
            return  bkvData.getIntegerValue();
        }
        return null;
    }

    public Double getBKVDoubleValue(String key,Integer decimal){
        BKVData bkvData = bkvDataMap.get(key);
        if(bkvData != null){
            return bkvData.getDoubleValue(decimal);
        }
        return null;
    }

    public PlugBKVData getPlugInfo(Integer slotNum){
        if(slotNum == 1){
            BKVData bkvData = bkvDataMap.get(V1_CDCZConstants.KEY_SLOT_1);
            if(bkvData != null && bkvData.getValue() != null && bkvData.getValue().length > 0){
                return new PlugBKVData(bkvData.getValue());
            }
        }else if(slotNum == 2){
            BKVData bkvData = bkvDataMap.get(V1_CDCZConstants.KEY_SLOT_2);
            if(bkvData != null && bkvData.getValue() != null && bkvData.getValue().length > 0){
                return new PlugBKVData(bkvData.getValue());
            }
        }else if(slotNum == 3){
            BKVData bkvData = bkvDataMap.get(V1_CDCZConstants.KEY_SLOT_3);
            if(bkvData != null && bkvData.getValue() != null && bkvData.getValue().length > 0){
                return new PlugBKVData(bkvData.getValue());
            }
        }else if(slotNum == 4){
            BKVData bkvData = bkvDataMap.get(V1_CDCZConstants.KEY_SLOT_4);
            if(bkvData != null && bkvData.getValue() != null && bkvData.getValue().length > 0){
                return new PlugBKVData(bkvData.getValue());
            }
        }else if(slotNum == 5){
            BKVData bkvData = bkvDataMap.get(V1_CDCZConstants.KEY_SLOT_5);
            if(bkvData != null && bkvData.getValue() != null && bkvData.getValue().length > 0){
                return new PlugBKVData(bkvData.getValue());
            }
        }else if(slotNum == 6){
            BKVData bkvData = bkvDataMap.get(V1_CDCZConstants.KEY_SLOT_6);
            if(bkvData != null && bkvData.getValue() != null && bkvData.getValue().length > 0){
                return new PlugBKVData(bkvData.getValue());
            }
        }else if(slotNum == 7){
            BKVData bkvData = bkvDataMap.get(V1_CDCZConstants.KEY_SLOT_7);
            if(bkvData != null && bkvData.getValue() != null && bkvData.getValue().length > 0){
                return new PlugBKVData(bkvData.getValue());
            }
        }else if(slotNum == 8){
            BKVData bkvData = bkvDataMap.get(V1_CDCZConstants.KEY_SLOT_8);
            if(bkvData != null && bkvData.getValue() != null && bkvData.getValue().length > 0){
                return new PlugBKVData(bkvData.getValue());
            }
        }else if(slotNum == 9){
            BKVData bkvData = bkvDataMap.get(V1_CDCZConstants.KEY_SLOT_9);
            if(bkvData != null && bkvData.getValue() != null && bkvData.getValue().length > 0){
                return new PlugBKVData(bkvData.getValue());
            }
        }else if(slotNum == 10){
            BKVData bkvData = bkvDataMap.get(V1_CDCZConstants.KEY_SLOT_10);
            if(bkvData != null && bkvData.getValue() != null && bkvData.getValue().length > 0){
                return new PlugBKVData(bkvData.getValue());
            }
        }
        return null;
    }

    public Map<String,BKVData> getBKVDataMap(){
        return this.bkvDataMap;
    }
}
